package hole

import (
	"fmt"
	"math/rand/v2"
)

var sunSigns = [...]sunSign{
	{3, 21, 31, "♈", []string{"♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑"}},
	{4, 1, 19, "♈", []string{"♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑"}},
	{4, 20, 30, "♉", []string{"♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒"}},
	{5, 1, 20, "♉", []string{"♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒"}},
	{5, 21, 31, "♊", []string{"♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓"}},
	{6, 1, 21, "♊", []string{"♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓"}},
	{6, 22, 30, "♋", []string{"♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈"}},
	{7, 1, 22, "♋", []string{"♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈"}},
	{7, 23, 31, "♌", []string{"♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉"}},
	{8, 1, 22, "♌", []string{"♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉"}},
	{8, 23, 31, "♍", []string{"♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊"}},
	{9, 1, 22, "♍", []string{"♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊"}},
	{9, 23, 30, "♎", []string{"♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋"}},
	{10, 1, 22, "♎", []string{"♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋"}},
	{10, 23, 31, "♏", []string{"♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌"}},
	{11, 1, 22, "♏", []string{"♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌"}},
	{11, 23, 30, "♐", []string{"♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍"}},
	{12, 1, 21, "♐", []string{"♎", "♎", "♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍"}},
	{12, 22, 31, "♑", []string{"♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎"}},
	{1, 1, 19, "♑", []string{"♏", "♏", "♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎"}},
	{1, 20, 31, "♒", []string{"♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏"}},
	{2, 1, 18, "♒", []string{"♐", "♐", "♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏"}},
	{2, 19, 28, "♓", []string{"♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐"}},
	{3, 1, 20, "♓", []string{"♑", "♑", "♒", "♒", "♓", "♓", "♈", "♈", "♉", "♉", "♊", "♊", "♋", "♋", "♌", "♌", "♍", "♍", "♎", "♎", "♏", "♏", "♐", "♐"}},
}

type sunSign struct {
	month, startDate, endDate int
	symbol                    string
	risingSymbols             []string
}

func (s sunSign) randomDate(hour int) test {
	return s.test(randInt(s.startDate, s.endDate), hour)
}

func (s sunSign) edgeDate(hour int) test {
	day := s.startDate
	if day == 1 {
		day = s.endDate
	}
	return s.test(day, hour)
}

func (s sunSign) test(day int, hour int) (t test) {
	t.in = fmt.Sprintf("%02d-%02d %02d:%02d", s.month, day, hour, rand.IntN(60))

	if risingSymbol := s.risingSymbols[hour]; risingSymbol == s.symbol {
		t.out = s.symbol
	} else {
		t.out = s.symbol + risingSymbol
	}

	return
}

var _ = answerFunc("zodiac-signs", func() []Answer {
	const (
		randomCases = 20
		hours       = 24
		totalCases  = randomCases + len(sunSigns) + len(sunSigns)*hours
	)

	tests := make([]test, randomCases, totalCases)

	for i := range randomCases {
		tests[i] = randChoice(sunSigns[:]).randomDate(rand.IntN(hours))
	}

	for _, sunSign := range sunSigns {
		tests = append(tests, sunSign.edgeDate(rand.IntN(hours)))
		for hour := 0; hour < hours; hour++ {
			tests = append(tests, sunSign.randomDate(hour))
		}
	}

	return outputTests(shuffle(tests))
})
